package com.winchain.provider.expiration.cmd;

import com.shell.bee.acct.account.util.VirtualAcctUtil;
import com.shell.bee.persistence.transaction.Transaction;
import com.shell.bee.persistence.transaction.TransactionUtil;
import com.shell.framework.command.CommandContext;
import com.shell.framework.command.ICommand;
import com.winchain.basic.exception.ExtException;
import com.winchain.chainbill.ChainBillUtil;
import com.winchain.provider.expiration.po.CbCredit;
import com.winchain.provider.expiration.po.CbDebit;
import com.winchain.provider.expiration.rx.BillExpirationEvent;
import com.winchain.provider.expiration.service.CbCreditService;
import com.winchain.provider.expiration.service.CbDebitService;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class BillExpCreditExeCmd implements ICommand<BillExpirationEvent> {
	protected final Log logger = LogFactory.getLog(getClass());
	@Autowired
	private CbCreditService cbCreditService;
	@Autowired
	private CbDebitService cbDebitService;

	public boolean execute(CommandContext<BillExpirationEvent> context) throws Exception {
		BillExpirationEvent event = (BillExpirationEvent) context.getSource();
		String expDate = event.getDate();
		String grpId = event.getGrpId();
		if ("single".equals(ChainBillUtil.getExpSettleMode(grpId))) {
			exeCreditWithSingleMode(expDate, grpId);
		} else {
			List<CbCredit> cbCredits = this.cbCreditService.getBillCredits(expDate, grpId, "0", null);
			for (final CbCredit cbCredit : cbCredits) {
				TransactionUtil.execute(new Transaction() {
					public void doInTransaction() {
						CbDebit debit = (CbDebit) BillExpCreditExeCmd.this.cbDebitService
								.selectByKey(cbCredit.getDebitId());
						if (debit != null) {
							if (debit != null) {
								if (!"1".equals(debit.getDebitState())) {
								}
							}
						} else {
							BillExpCreditExeCmd.this.logger.info("������������");
							try {
								String remark = "��������-������������";
								if (debit == null) {
									remark = "������������";
								} else if ("2".equals(cbCredit.getCreditType())) {
									remark = "��������-����������";
								}
								BillExpCreditExeCmd.this.cbCreditService.creditById(cbCredit.getCreditId(), true,
										remark);
							} catch (Exception e) {
								e.printStackTrace();
								BillExpCreditExeCmd.this.logger.error(getClass() + "��������", e);
								throw new ExtException(e.getMessage());
							}
						}
						BillExpCreditExeCmd.this.logger.info("��������������������������������ID��"
								+ cbCredit.getCreditId() + "������ID��" + cbCredit.getDebitId());
					}
				}, new int[0]);
			}
		}
		return false;
	}

	private void exeCreditWithSingleMode(String expDate, String grpId) {
		List<CbDebit> cbDebits = this.cbDebitService.selectDebitBill(expDate, grpId, new String[] { "0" });
		for (Iterator<CbDebit> localIterator = cbDebits.iterator(); localIterator.hasNext();) {
			CbDebit debit = localIterator.next();
			if ((ChainBillUtil.onlinePay()) && (VirtualAcctUtil.onVirtual())
					&& (!this.cbDebitService.enoughBalance(debit, grpId))) {
				this.logger.warn("����[" + debit.getAcctNo() + "]��������");
			} else {
				boolean retFlag = this.cbCreditService.batchCreditByDebitId(debit.getDebitId(), debit.getCusId(), true,
						false);
				String debitState = "2";
				if (retFlag) {
					debitState = "1";
					debit.setActualAmount(debit.getBillAmount());
					debit.setSettleDate(debit.getDebitDate());
				}
				debit.setDebitState(debitState);
				this.cbDebitService.updateNotNull(debit);
			}
		}
		List<CbCredit> cbCredits = this.cbCreditService.getBillCredits(expDate, grpId, "0", "1");
		for (final CbCredit cbCredit : cbCredits) {
			TransactionUtil.execute(new Transaction() {
				public void doInTransaction() {
					BillExpCreditExeCmd.this.logger.info("����������������");
					try {
						String remark = "������������";
						BillExpCreditExeCmd.this.cbCreditService.creditById(cbCredit.getCreditId(), true, remark);
					} catch (Exception e) {
						e.printStackTrace();
						BillExpCreditExeCmd.this.logger.error(getClass() + "��������", e);
						throw new ExtException(e.getMessage());
					}
				}
			}, new int[0]);
		}
	}
}
